import 'dart:async';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:x3_charts_core/chart_painter/new_generic_stacked_chart_painter.dart';
import 'package:x3_charts_core/model/general_chart_model.dart';

///**
///* @author hrongyong
///* @date   1/26/21
///* @email hrongyong@gmail.com
///* Description: 新的通用层叠图表
///*/

class NewGenericStackedChartWidget extends StatefulWidget {
  final List<GeneralChartModel> chartList;

  ///最大显示多少个直方
  final int maxItemCount;

  ///背景颜色
  final Color bgColor;

  ///底坐标颜色
  final Color bottomCoordinateColor;

  ///底坐标文本大小
  final double bottomCoordinateTextSize;

  ///是否要绘画x轴name上面的刻度线
  final bool drawXTickMark;

  ///第一个直方图的颜色
  final Color firstHistogramColor;

  ///第一个直方图描述的前缀
  final String firstHistogramDescriptionPrefix;

  ///第二个直方图的颜色
  final Color secondHistogramColor;

  ///第二个直方图描述的前缀
  final String secondHistogramDescriptionPrefix;

  ///第三个直方图的颜色
  final Color thirdHistogramColor;

  ///第三个直方图描述的前缀
  final String thirdHistogramDescriptionPrefix;

  ///第一个折线的颜色
  final Color firstPolylineColor;

  ///第一个折线描述的前缀
  final String firstPolylineDescriptionPrefix;

  ///第二个折线的颜色
  final Color secondPolylineColor;

  ///第二个折线描述的前缀
  final String secondPolylineDescriptionPrefix;

  ///是否要显示数据
  final bool isDisplayData;

  ///异常颜色-目前只用于直方图
  final Color abnormalColor;

  ///左边Y轴最大值
  final int leftYAxisMax;

  ///左边Y轴的单位
  final String leftYAxisUnit;

  ///右边Y轴最大值
  final int rightYAxisMax;

  ///右边Y轴的单位
  final String rightYAxisUnit;

  ///是否跳到列表最后
  final bool animateTo;

  ///文字距离坐标轴/刻度线的距离
  final double textDistanceAxisSize;

  NewGenericStackedChartWidget({
    Key key,
    @required this.chartList,
    this.firstHistogramColor = Colors.blue,
    this.firstHistogramDescriptionPrefix = "",
    this.secondHistogramColor = Colors.lightBlue,
    this.secondHistogramDescriptionPrefix = "",
    this.thirdHistogramColor = Colors.lightBlueAccent,
    this.thirdHistogramDescriptionPrefix = "",
    this.firstPolylineColor = Colors.orange,
    this.firstPolylineDescriptionPrefix = "",
    this.secondPolylineColor = Colors.orangeAccent,
    this.secondPolylineDescriptionPrefix = "",
    this.bgColor = Colors.white,
    this.bottomCoordinateColor = Colors.white,
    this.abnormalColor = const Color.fromARGB(255, 194, 194, 194),
    this.drawXTickMark = false,
    this.isDisplayData = false,
    this.leftYAxisMax,
    this.leftYAxisUnit = "",
    this.rightYAxisUnit = "",
    this.rightYAxisMax,
    this.maxItemCount = 14,
    this.animateTo = false,
    this.bottomCoordinateTextSize = 12.0,
    this.textDistanceAxisSize = 4.0,
  });

  @override
  _NewGenericStackedChartWidgetState createState() => _NewGenericStackedChartWidgetState();
}

class _NewGenericStackedChartWidgetState extends State<NewGenericStackedChartWidget> with SingleTickerProviderStateMixin {
  ScrollController _scrollController = ScrollController(initialScrollOffset: 0.0);

  AnimationController _controller;
  double progress = 0.0;

  ///{"dx":dx,"index":index}
  ValueNotifier<Map<String, dynamic>> _notifier = ValueNotifier({"dx": 0.0, "progress": 0.0});

  double dx = 0;

  int _index;

  ///左边间距
  double leftMargin = 0.0;

  ///右边间距
  double rightMargin = 0.0;

  ///底部间距
  double bottomMargin = 15.0;

  ///间距
  EdgeInsets chartPadding;

  ///更新滑动坐标
  _onPanUpdate(double offset) {
    dx = offset;
    _notifier.value = {"dx": dx, "index": _index, "progress": progress};
  }

  ///更新动画进度
  updateAnimationProgress(double animationProgress) {
    progress = animationProgress;
    _notifier.value = {"dx": dx, "index": _index, "progress": progress};
  }

  bool isLoaded = true;

  @override
  void initState() {
    super.initState();

    _scrollController.addListener(() {
      _onPanUpdate(_scrollController.offset);
    });

    _controller = AnimationController(
      duration: const Duration(milliseconds: 1000),
      vsync: this,
    )..forward();
    _controller.addListener(() {
      updateAnimationProgress(_controller.value);
    });
  }

  @override
  void dispose() {
    _scrollController?.dispose();
    _controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (widget.chartList == null || widget.chartList.length == 0) return Container();

    ///确定左边和下边的距离
    if (widget.leftYAxisMax != null) {
      TextPainter painter01 = TextPainter(
          maxLines: 1,
          textDirection: TextDirection.ltr,
          text: TextSpan(
              text: widget.leftYAxisMax.toString() + widget.leftYAxisUnit,
              style: TextStyle(
                fontSize: 10,
              )));
      painter01.layout();
      leftMargin = painter01.width;
      bottomMargin = painter01.height;
    }
    if (widget.rightYAxisMax != null) {
      ///确定右边的距离
      TextPainter painter02 = TextPainter(
          maxLines: 1,
          textDirection: TextDirection.ltr,
          text: TextSpan(
              text: widget.rightYAxisMax.toString() + widget.rightYAxisUnit,
              style: TextStyle(
                fontSize: 10,
              )));
      painter02.layout();
      rightMargin = painter02.width;
    }
    chartPadding = EdgeInsets.only(left: leftMargin + 2, bottom: bottomMargin + 4, right: rightMargin + 4, top: 10);

    return Container(
      child: LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
          double maxWidth = constraints.maxWidth - chartPadding.left - chartPadding.right;
          double itemExtent = widget.chartList.length > widget.maxItemCount ? maxWidth / widget.maxItemCount : maxWidth / widget.chartList.length;
          if (isLoaded && widget.animateTo) {
            isLoaded = false;
            Timer(
              Duration(milliseconds: 500),
              () => _scrollController.animateTo(
                _scrollController.position.maxScrollExtent,
                duration: Duration(milliseconds: 500),
                curve: Curves.bounceInOut,
              ),
            );
          }
          return CustomPaint(
            size: Size(constraints.maxWidth, constraints.maxHeight),
            child: Padding(
              padding: chartPadding,
              child: ListView.builder(
                scrollDirection: Axis.horizontal,
                controller: _scrollController,
                itemCount: widget.chartList.length,
                itemExtent: itemExtent,
                itemBuilder: (BuildContext context, int index) {
                  return InkWell(
                    onTap: () {
                      if (progress >= 1.0) {
                        _index = index;
                        _notifier.value = {"dx": dx, "index": _index, "progress": progress};
                      }
                    },
                    child: Container(
                      width: itemExtent,
                      height: double.infinity,
                    ),
                  );
                },
              ),
            ),
            foregroundPainter: NewGenericStackedChartPainter(
              notifier: _notifier,
              chartPadding: chartPadding,
              leftYAxisMax: widget.leftYAxisMax,
              leftYAxisUnit: widget.leftYAxisUnit,
              rightYAxisMax: widget.rightYAxisMax,
              rightYAxisUnit: widget.rightYAxisUnit,
              chartList: widget.chartList,
              bgColor: widget.bgColor,
              maxItemCount: widget.maxItemCount,
              drawXTickMark: widget.drawXTickMark,
              firstHistogramColor: widget.firstHistogramColor,
              firstHistogramDescriptionPrefix: widget.firstHistogramDescriptionPrefix,
              secondHistogramColor: widget.secondHistogramColor,
              secondHistogramDescriptionPrefix: widget.secondHistogramDescriptionPrefix,
              thirdHistogramColor: widget.thirdHistogramColor,
              thirdHistogramDescriptionPrefix: widget.thirdHistogramDescriptionPrefix,
              firstPolylineColor: widget.firstPolylineColor,
              firstPolylineDescriptionPrefix: widget.firstPolylineDescriptionPrefix,
              secondPolylineColor: widget.secondPolylineColor,
              secondPolylineDescriptionPrefix: widget.secondPolylineDescriptionPrefix,
              isDisplayData: widget.isDisplayData,
              abnormalColor: widget.abnormalColor,
              bottomCoordinateColor: widget.bottomCoordinateColor,
              bottomCoordinateTextSize: widget.bottomCoordinateTextSize,
              textDistanceAxisSize: widget.textDistanceAxisSize,
            ),
          );
        },
      ),
    );
  }
}
